package com.czkevin.guicontrolsapi.tests;

import com.czkevin.guicontrolsapi.GUIControlsAPI;
import com.czkevin.guicontrolsapi.controls.*;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.czkevin.guicontrolsapi.ItemUtils;
import com.czkevin.guicontrolsapi.Window;

import java.lang.reflect.Method;

public class GUITestCommand implements CommandExecutor {
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if(!Player.class.isAssignableFrom(sender.getClass())) return true;
        if(!sender.hasPermission("guicontrolsapi.command.guitest")) return true;
        Player p = (Player) sender;
        if(args.length == 0) {
            Method[] methods = getClass().getDeclaredMethods();
            for(Method m : methods) {
                if(m.getName().startsWith("test_") && m.getName().length() > 5) {
                    p.sendMessage("\u00a76/guitest " + m.getName().substring(5));
                }
            }
            return true;
        }
        try {
            Method m = getClass().getDeclaredMethod("test_" + args[0], Player.class);
            m.invoke(null, p);
            p.sendMessage("\u00a7aTest performed! ");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    public static void test_simple(Player p) {
        Window w = new Window("Test Window", 20, 15, 20) {
            @Override
            public void onOpenInternal(HumanEntity target) {
                target.sendMessage("wow you opened! ");
            }

            @Override
            public boolean onCloseInternal(HumanEntity target) {
                target.sendMessage("refused to close! ");
                return false;
            }

            @Override
            public void onDestroy() {
                System.out.println("destroyed");
            }
        };

        w.setControl(0, 0, new LabelControl(
                "just some text",
                "lol\nhaha\njk"
        ));

        w.setControl(0, 2, new BlinkingLightControl(
                new ItemStack(Material.BLACK_STAINED_GLASS_PANE),
                new ItemStack(Material.ORANGE_STAINED_GLASS_PANE),
                800
        ));

        w.setControl(7, 0, new ButtonControl(null, (clicked) -> {
            clicked.sendMessage("you clicked this! " + clicked.getName());
        }, "TEST BUTTON", "some text? \nyeah! "));

        w.setControl(7, 3, new ButtonControl(new ItemStack(Material.BARRIER), (clicked) -> {
            clicked.sendMessage("you tried to close " + clicked.getName());
            w.close(clicked);
        }, "Close Window", "some text? \nyeah! "));

        w.setControl(15, 2, new LabelControl("\u00a7aInput String", "\u00a7cnot set"));
        w.setControl(16, 2, new ButtonControl(new ItemStack(Material.WRITABLE_BOOK), humanEntity -> {
            GUIControlsAPI.getInstance().getInputWindowManager().openInput((Player) humanEntity, "Edit text", "text", (name, value) -> {
                GUIControl c = w.getControlAt(15, 2);
                ((LabelControl) c).setDescriptions("\u00a77Your input is: \n" + (value == null ? "\u00a7cnot set" : "\u00a7e" + value));
                c.onRender(true);
            }, w);
        }, "\u00a76Click to Edit", "just click! "));

        w.setControl(2, 1, new ButtonControl(new ItemStack(Material.CLOCK), (clicked) -> { }, "Time Display", "...") {
            @Override
            public void onRender(boolean force) {
                super.onRender(force);
                getWindow().setDisplayItemAt(getX(), getY(), ItemUtils.putMeta(display, false, "Time", "\u00a7a" + java.time.Instant.now().toString()));
            }
        });

        w.setControl(5, 1, new IndicatorSwitchControl(new ItemStack(Material.LEVER), "Start / Stop", "It controls the engine. ", (changer, status) -> {
            changer.sendMessage("lol => " + status);
        }));

        w.open(p, null);
    }

    public static void test_updated(Player p) {
        Window w = new Window("Test Window", 36, 20) {
            @Override
            public void onOpenInternal(HumanEntity target) {
                target.sendMessage("wow you opened timer! ");
            }

            @Override
            public boolean onCloseInternal(HumanEntity target) {
                target.sendMessage("ok closed");
                return true;
            }

            @Override
            public void onDestroy() {
                System.out.println("destroyed");
            }
        };

        w.open(p, null);
    }

    public static void test_input(Player p) {
        Window parent = new Window("Create town", 10, 10) {
            @Override
            public void onOpenInternal(HumanEntity target) {

            }

            @Override
            protected boolean onCloseInternal(HumanEntity target) {
                return true;
            }

            @Override
            public void onDestroy() {

            }
        };
        parent.setControl(0, 0, new LabelControl("not set", ""));
        parent.setControl(1, 0, new ButtonControl(new ItemStack(Material.WRITABLE_BOOK), "\u00a7aEdit", "\u00a7bClick to edit! "));

        ((ButtonControl) parent.getControlAt(1, 0)).setHandler(humanEntity -> {
            if(!Player.class.isAssignableFrom(humanEntity.getClass())) return;
            GUIControlsAPI.getInstance().getInputWindowManager().openInput((Player) humanEntity, "Edit Town Name", "test", (name, value) -> {
                ((LabelControl) parent.getControlAt(0, 0)).setLabel(value == null ? "\u00a7cNOT SET" : value);
                parent.getControlAt(0, 0).onRender(true);
                System.out.println("callback called: " + value);
            }, parent);
        });

        parent.open(p, null);
    }
}
